//
//  CDRefreshControl.swift
//  HomeSchoolDemo
//
//  Created by Mac on 16/10/9.
//  Copyright © 2016年 chendong. All rights reserved.
//

import UIKit

//临界点
fileprivate let CDRefreshOffset:CGFloat = 60

/// 刷新视图状态
///
/// - nomol:       普通状态(什么都不做)
/// - pulling:     超过临界点，如果放手就开始刷新
/// - willRefresh: 已经超过临界点，并且已经放手，准备开始刷新
enum CDRefreshState{
    case nomol
    case pulling
    case willRefresh
}


class CDRefreshControl: UIControl {

    //记录父视图
    fileprivate weak var scrollView:UIScrollView?
    //创建UI属性
    let refreshV = CDRefreshView.refreshV()
    
    
    init() {
        super.init(frame:CGRect())
        //设置UI
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
        setupUI()
               }
    //获得父类方法
    //这个方法是在执行addSubview 会调用  移除时也会调用
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        //判断一下
        guard let sv = newSuperview as? UIScrollView else {
            return
        }
        //记录父视图
        scrollView = sv
        
        //使用KVO添加父视图属性变化
        //KVO添加监听以后必须在当前视图销毁前移除，否则会直接崩溃
        //不同于通知，通知不移除时不会发生，但是会造成内存泄漏或重复添加
        sv.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
    }
    
    //当前视图移除时会调用
    override func removeFromSuperview() {
        //移除监听,必须在执行父类的方法前
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        super.removeFromSuperview()
        //
    }
    
    //KVO的监听回调方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        //print(scrollView?.contentOffset.y)
        guard let sv = scrollView else {
            return
        }
        //获得高度
        let H = -(sv.contentOffset.y + sv.contentInset.top)
        //屏蔽向上滚动出屏幕的功能
        if H < 0 {
            return
        }
        
        //如果是拖拽情况下
        if sv.isDragging{
            if H > CDRefreshOffset && refreshV.refreshState == .nomol{
                //print("手放开就刷新数据")
                refreshV.refreshState = .pulling
                //没放手状态下返回
            }else if H < CDRefreshOffset && refreshV.refreshState == .pulling{
                //print("再用点力")
                refreshV.refreshState = .nomol
            }
        }else{
            //进入这里表示拖拽结束，如果是超过临界点就开始刷新
            if refreshV.refreshState == .pulling {
                //print("刷新数据")
                //beginRefreshing()
                //发送时间消息
                sendActions(for: .valueChanged)
            }
        }

        
        //设置控件高度
        self.frame = CGRect(x: 0,
                            y: -H,
                            width: UIScreen.main.bounds.width,
                            height: H)
    }
    
    ///开始刷新
    open func beginRefreshing(){
        guard let sv = scrollView else {
            return
        }
        if refreshV.refreshState == .willRefresh {
            return
        }
        
        //已经进入刷新数据状态
        refreshV.refreshState = .willRefresh
        
        //保持刷新状态
        
        var inset = sv.contentInset
        inset.top += CDRefreshOffset
        sv.contentInset = inset

    }
    
    ///结束刷新
    open func endRefreshing(){
        guard let sv = scrollView else {
            return
        }
        
        if refreshV.refreshState != .willRefresh {
            return
        }
        
        //调整父视图高度
            UIView.animate(withDuration: 0.25, animations: {
            var inset = sv.contentInset
            inset.top -= CDRefreshOffset
            sv.contentInset = inset
            }) { (_) in
                //修改状态
                self.refreshV.refreshState = .nomol
        }
    }
}

extension CDRefreshControl {
    fileprivate func setupUI() {
        
        //添加视图
        addSubview(refreshV)
        
        //backgroundColor = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)
        //裁剪超出边界的图片
        //clipsToBounds = true
        //使用原生的约束框架，必须先关掉系统的自动设置约束的属性
        //storyboard 会自动关闭，纯代码需手动设置下面这个属性为false
        refreshV.translatesAutoresizingMaskIntoConstraints = false
        //设置中心X
        addConstraint(NSLayoutConstraint(item: refreshV, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0))
        
        //设置中心Y
        addConstraint(NSLayoutConstraint(item: refreshV, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0))
        //宽
        addConstraint(NSLayoutConstraint(item: refreshV, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: refreshV.bounds.width))
        //高
        addConstraint(NSLayoutConstraint(item: refreshV, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: refreshV.bounds.height))
    }
    
}



